package cn.wxt.ssmtemplete.configuration;

import java.beans.PropertyVetoException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
 * mybatis - spring 配置
 * DaoConfiguration
 * @author Aaron 2017年11月19日
 */
@Configuration
public class DaoConfiguration {
    
    /**
     * 数据库连接池
     * @return
     */
    @Bean
    public ComboPooledDataSource dataSource(){
        //获取Properties属性
        Properties propertie = new Properties();
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        try {
            InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("jdbc.properties");
            propertie.load(inputStream);
            //为数据源注入属性
            dataSource.setDriverClass(propertie.getProperty("jdbc.driver"));
            dataSource.setJdbcUrl(propertie.getProperty("jdbc.url"));
            dataSource.setUser(propertie.getProperty("jdbc.username"));  
            dataSource.setPassword(propertie.getProperty("jdbc.password"));
            dataSource.setMaxPoolSize(Integer.parseInt(propertie.getProperty("c3p0.maxPoolSize")));
            dataSource.setMinPoolSize(Integer.parseInt(propertie.getProperty("c3p0.minPoolSize")));
            dataSource.setAutoCommitOnClose(propertie.getProperty("c3p0.autoCommitOnClose").equals("true"));
            dataSource.setCheckoutTimeout(Integer.parseInt(propertie.getProperty("c3p0.checkoutTimeout")));
            dataSource.setAcquireRetryAttempts(Integer.parseInt(propertie.getProperty("c3p0.acquireRetryAttempts")));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        
        return dataSource;
    }
    
    /**
     * 配置SqlSessionFactory对象
     * @param comboPooledDataSource
     * @return
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(ComboPooledDataSource comboPooledDataSource){
        SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
        //注入数据库连接池 
        sqlSessionFactory.setDataSource(comboPooledDataSource);
        //扫描model包 使用别名
        sqlSessionFactory.setTypeAliasesPackage("cn.wxt.ssmtemplete.model");
        //扫描sql配置文件:mapper需要的xml文件
        /**
         * 相当于这条<property name="mapperLocations" value="classpath:mapper/*.xml"/>
         */
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            sqlSessionFactory.setMapperLocations(resolver.getResources("classpath:Mapper/*.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sqlSessionFactory;
    }
    
    /**
     * 配置扫描Dao接口包，动态实现Dao接口，注入到spring容器中
     * @return
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer config = new MapperScannerConfigurer();
        //注入sqlSessionFactory
        config.setSqlSessionFactoryBeanName("sqlSessionFactory");
        //给出需要扫描Dao接口包
        config.setBasePackage("cn.wxt.ssmtemplete.dao");
        return config;
    }
    
    /**
     * 配置事务管理器
     * @param comboPooledDataSource
     * @return
     */
    @Bean
    public DataSourceTransactionManager transactionManager(ComboPooledDataSource comboPooledDataSource){
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        //注入数据库连接池
        dataSourceTransactionManager.setDataSource(comboPooledDataSource);
        return dataSourceTransactionManager;
    }
    
    
}
